package org.ala.shopping_test.shopping_center.repository.order_buyer.dao;

import java.util.List;

import org.ala.shopping_test.shopping_center.repository.order_buyer.entity.ShoppingOrderBuyerDO;
import org.ala.shopping_test.shopping_center.repository.order_buyer.entity.ShoppingOrderBuyerFields;
import org.ala.shopping_test.shopping_center.repository.order_buyer.entity.ShoppingOrderBuyerPagerCountDO;
import org.ala.shopping_test.shopping_center.repository.order_buyer.orderBy.ShoppingOrderBuyerOrderBy;
import org.ala.shopping_test.shopping_center.repository.order_buyer.query.ShoppingOrderBuyerQuery;
import org.ala.shopping_test.shopping_center.repository.order_buyer.router.ShoppingOrderBuyerDOListRouter;
import org.ala.shopping_test.shopping_center.repository.order_buyer.router.ShoppingOrderBuyerDORouter;
import org.ala.shopping_test.shopping_center.repository.order_buyer.router.ShoppingOrderBuyerMultipleUpdateListRouter;
import org.ala.shopping_test.shopping_center.repository.order_buyer.router.ShoppingOrderBuyerQueryRouter;
import org.ala.tiktools.mybatis.commons.AbstractMultipUpdate;
import org.ala.tiktools.mybatis.pager.Pagement;
import org.ala.tiktools.mybatis.pager.Pager;
import org.ala.tiktools.sharddb.mybatis.interceptor.Shard;
import org.ala.tiktools.sharddb.mybatis.pager.after_pager.ShardAfterPager;
import org.ala.tiktools.sharddb.mybatis.router.ShardRouter;
import org.ala.tiktools.sharddb.mybatis.transaction.ShardTransaction;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 *	Dao (shopping_order_buyer)
 *  订单总表
 *
 *	@author 骆毅 (ala)
 *	@date 2025-03-24 15:40:25
 */
@Mapper
public interface ShoppingOrderBuyerMapper {
    /**
     *  查询全部数据（慎用！！！）
     */
    @Shard(autoCreateTable = true)
    List<ShoppingOrderBuyerDO> findAllWithShardSuffix(@Param("fields") ShoppingOrderBuyerFields fields, @Param("shardSuffix") String shardSuffix);


    /**
     *  条件查询
     *  <p> 如果queries中路由到多表，默认的aggregator会把结果按表名的ascii序拼接
     */
    @Shard(autoCreateTable = true)
    List<ShoppingOrderBuyerDO> findByQuery(
                @Param("fields") ShoppingOrderBuyerFields fields,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query);
    /**
     *  条件查询
     *  <p> 已经完整指定表名，无需router
     */
    @Shard(autoCreateTable = true)
    List<ShoppingOrderBuyerDO> findByQueryWithOrderBy(
                @Param("fields") ShoppingOrderBuyerFields fields,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query,
                @Param("orderBy") ShoppingOrderBuyerOrderBy orderBy);


    /**
     *  查询总数
     */
    @Shard(autoCreateTable = true)
    int count(@Param("shardSuffix") String shardSuffix);
    /**
     *  条件查询数量
     */
    @Shard(autoCreateTable = true)
    int countByQuery(@ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query);
    /**
     *  查询在执行limit条件下的数量和极值
     *  <p> 给分页用的，其他场景用不到
     */
    @Shard(autoCreateTable = true)
    ShoppingOrderBuyerPagerCountDO countByQueryWithOrderBy(
                @Param("page") Pager<ShoppingOrderBuyerDO> pager,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query,
                @Param("orderBy") ShoppingOrderBuyerOrderBy orderBy);
    /**
     *  查询极值左边的数量和等于极值的数量
     *  <p> 给分页用的，其他场景用不到
     *  <p> 极值保存在orderBy.getCurrentItem().getVal()中
     *  @return 0:极值左边的数量 1:等于极值的数量
     */
    @Shard(autoCreateTable = true)
    List<Integer> countByQueryWithExtreme(
                @Param("page") Pager<ShoppingOrderBuyerDO> pager,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query,
                @Param("orderBy") ShoppingOrderBuyerOrderBy orderBy);


    /**
     *  分页查询
     *  <p> 分页字段一定得是唯一键
     *  <p> 上一轮排序值存储在 orderBy.items.get(0).val 中
     *  <p> 通过orderBy对象进行传递，所以多轮查询之间需要共用一个orderBy对象
     *  <p> 或者orderBy.setFirstItemVal()传递
     */
    @Shard(autoCreateTable = true)
    @Pagement(count="countByQuery")
    Pager<ShoppingOrderBuyerDO> findByAfterPage(
                @Param("fields") ShoppingOrderBuyerFields fields,
                @Param("page") ShardAfterPager<ShoppingOrderBuyerDO> pager,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query,
                @Param("orderBy") ShoppingOrderBuyerOrderBy orderBy);
    /**
     *  分页查询
     *  <p> 会按照表名的ascii序，优先取前几张表凑够本页数量
     */
    @Shard(autoCreateTable = true)
    @Pagement(count="countByQuery")
    Pager<ShoppingOrderBuyerDO> findByPage(
                @Param("fields") ShoppingOrderBuyerFields fields,
                @Param("page") Pager<ShoppingOrderBuyerDO> pager,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query);
    /**
     *  分页查询
     *  <p> 如果queries中出现了多表，默认会按照orderBy中定义的顺序取pageSize条记录
     */
    @Shard(autoCreateTable = true)
    @Pagement(count="countByQuery")
    Pager<ShoppingOrderBuyerDO> findByPageWithOrderBy(
                @Param("fields") ShoppingOrderBuyerFields fields,
                @Param("page") Pager<ShoppingOrderBuyerDO> pager,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query,
                @Param("orderBy") ShoppingOrderBuyerOrderBy orderBy);


    /**
     *  插入
     *  <p> 如果存在唯一自增主键字段，则insert完成后该字段保存该条记录自增的值（不过shard模式下推荐分布式id，shard中自带SnowIdGenerator）
     */
    @Shard(autoCreateTable = true)
    @ShardTransaction
    void insert(@ShardRouter(router=ShoppingOrderBuyerDORouter.class) @Param("entity") ShoppingOrderBuyerDO entity);
    /**
     *  批量插入
     *  <p> 如果存在唯一自增主键字段，则insert完成后该字段保存该条记录自增的值（不过shard模式下推荐分布式id，shard中自带SnowIdGenerator）
     *  <p> 会调用 org.ala.tiktools.sharddb.mybatis.handler.IShardTableHandler 生成@Param("shardSuffix")参数
     *  <p> 如果 org.ala.tiktools.sharddb.mybatis.handler.IShardTableHandler 最终生成了多份 shardSuffix，分表之间组成本地分布式事务（单个分表走原生事务）
     */
    @Shard(autoCreateTable = true)
    @ShardTransaction
    void multipleInsert(@ShardRouter(router=ShoppingOrderBuyerDOListRouter.class) @Param("entities") List<ShoppingOrderBuyerDO> entities);


    /**
     *  修改
     *  <p> 注：如果修改了分偏键，这里不会进行迁移
     */
    @Shard(autoCreateTable = true)
    @ShardTransaction
    int update(@Param("entity") ShoppingOrderBuyerDO entity,
                @ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query);
    /**
     *  批量修改
     *  <p> 每个MultipleUpdate对应一个update语句
     *  <p> 在某些mysql + mybatis的版本中，可能只返回第一条update的影响行数
     */
    @Shard(autoCreateTable = true)
    @ShardTransaction
    int multipleUpdate(@ShardRouter(router=ShoppingOrderBuyerMultipleUpdateListRouter.class) @Param("updates") List<MultipleUpdate> multipleUpdates);


    /**
     *  删除
     */
    @Shard(autoCreateTable = true)
    @ShardTransaction
    int delete(@ShardRouter(router=ShoppingOrderBuyerQueryRouter.class) @Param("query") ShoppingOrderBuyerQuery query);


    /**
     *  建表语句
     *  <p> 只能建当前线程环境的分库下的分表。如果要自行调用，需要ThreadLocalLookupKey指定分库，不指定则默认default分库
     *  <p> 分库信息在 ShardDBConfiguration.DBS 查看
     */
    void createTable(@Param("shardSuffix") String shardSuffix);
    /**
     *  所有分表
     *  <p> 只能查看当前线程环境指定的分库下，的所有分表
     *  <p> 要看所有分库可以从 ShardDBConfiguration.DBS 里拿所有分库配置，自行遍历
     */
    List<String> allTables();


    /**
     *  批量修改参数
     */
    public static class MultipleUpdate extends AbstractMultipUpdate<ShoppingOrderBuyerDO, ShoppingOrderBuyerQuery> {
        public MultipleUpdate(ShoppingOrderBuyerDO entity, ShoppingOrderBuyerQuery query) {
            super(entity, query);
        }
        public static MultipleUpdate build(ShoppingOrderBuyerDO entity, ShoppingOrderBuyerQuery query) {
            return new MultipleUpdate(entity, query);
        }
        /**
         *  copy（注：这是浅拷贝）
         */
        public MultipleUpdate copy() {
            return new MultipleUpdate(entity.copy(), query.copy());
        }
    }
}